/**
 * 检测计划类
 * created by wuyp on 2019-05-15 20:22:57.
 */
import Vue from 'vue'
import { getPlanItemSD, getPlanItemED, getPlanItemDefineOrderByCode, getTrueOrderMsg, getReleasePlanAccountCode, getConstraintKeepDays, isBridgePlanItem, getBridgeCanUseAmout, isNeedCheckKeeyDays } from '@/utils/monplan/monthlyPlanUtils.js'
import { computeDateDiff, compareDate, getFormatDateBeforeOrAfter, isCommonMonth, isCommonQuarter, isCommonYear } from '@/utils/dateUtils.js'
import { isDefHoliday } from '@/utils/monplan/calendarUtils'

// 常量-顺序类型：小于L，大于M
const ORDER_TYPE_LESS_THAN = 'L'
const ORDER_TYPE_MORE_THAN = 'M'
// 常量-删除状态：0未删除，1已删除
const DEL_STATUS_0 = 0

 /**
 * 检测计划
 * 1. 传参：待检测的专项计划详情【或计划数组】
 * 2. 遍历 [待检测的计划]：将检测失败的信息放入检测结果数组
 * 3. 返回检测结果数组(有警告的计划项被标记:  warendInfo: {
 *         'isWarned': true, // true表示检测不通过，false表示检测通过
 *         'warnedMsg': '计划项顺序错误，发行应XXX'  // isWarned = false时，warnedMsg = ‘’
 *       })
 *
 * 检测点：
 *    0. 检测计划项时间：开始日和结束日都不属于周末和节假日【20190530新增检测项】
 *    1. 检测计划项顺序：时间先后顺序应满足
 *      1.1 提单1 < 律所进场1 && 提单2 < 律所进场2
 *      1.2 过桥 <= 缴款<= 发行
 *      1.3 定稿 < 配售 < 缴款 <= 发行
 *      1.4 律所进场必须在对应的提单日2-4日之内开始：提单结束日+2<=律所进场开始日<=提单结束日+4
 *      1.5 过桥和定稿先后顺序不一定，过桥和配售先后顺序也不一定，谁先谁后都可以，但是定稿<配售
 *    2. 检测计划项持续天数：律所进场持续时间4-8日 （此规则作为开关，默认关闭）
 *    3. 检测过桥约束：
 *      [3.1 检测过桥额度：是否超过当前可用额度]
 *      3.2 是否达到单期最小使用天数（发行日-过桥日）
 *      3.3 是否跨月
 *      3.4 是否跨季
 *      3.5 是否跨年
 *      3.6 是否满足托管行需求：专项计划的托管行id是否满足过桥机构的绑定托管需求
 * @param {Array} specialPlanDetailList 待检测的专项计划分档明细数据
 * @param {Array} specbasList 专项计划基础数据
 * @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @returns {*} 检测结果
 */
export function checkPlans (specialPlanDetailList, specbasList, specLoan, bridAmountInfoList) {
  if (Vue.prototype.UtilJs.isEmpty(specialPlanDetailList) || specialPlanDetailList.length <= 0 ||
    Vue.prototype.UtilJs.isEmpty(specbasList) || specbasList.length <= 0) {
    return []
  }
  return buildWarnedXQInfo(specialPlanDetailList, specbasList, specLoan, bridAmountInfoList)
}

/**
 * 1.构造有警告的小期信息列表[计划项信息]
 * @param {Array} specialPlanDetailList 专项计划分档明细数据
 * @param {Array} specbasList 专项计划基础数据
 * @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @return {Array} 有警告的专项计划信息列表
 */
export function buildWarnedXQInfo (specialPlanDetailList, specbasList, specLoan, bridAmountInfoList) {
  let warnedSPlanDetailArr = []
  if (Vue.prototype.UtilJs.isEmpty(specialPlanDetailList) || Vue.prototype.UtilJs.isEmpty(specbasList)) {
    return null
  }
  // 遍历每个专项计划
  for (var curSPlanInfo of specialPlanDetailList) {
    var xqPlanInfo = {}
    xqPlanInfo.keyId = curSPlanInfo.keyId               // 表主键
    xqPlanInfo.dueDate = curSPlanInfo.dueDate           // 应收账款到期日
    xqPlanInfo.filingPosition = curSPlanInfo.filingPosition   // 档位
    xqPlanInfo.projectId = curSPlanInfo.projectId       // 项目Id
    xqPlanInfo.projectName = curSPlanInfo.projectName   // 项目名称
    xqPlanInfo.specialPlanFilingName = curSPlanInfo.specialPlanFilingName   // 专项计划分档名称
    xqPlanInfo.specialPlanId = curSPlanInfo.specialPlanId    // 专项计划id
    xqPlanInfo.specialPlanPeriods = curSPlanInfo.specialPlanPeriods         // 专项计划期数
    xqPlanInfo.delStatus = curSPlanInfo.delStatus

    // 根据专项计划ID获取对应的专项计划基础数据信息
    var specPlanBasicInfo = specbasList.find(specPlan => {
      return specPlan.keyId === curSPlanInfo.specialPlanId
    })
    // 2.构造小期中-有警告的计划数据
    xqPlanInfo.specialPlanFilingDetails = buildWarnedReportData(specPlanBasicInfo, curSPlanInfo.specialPlanFilingDetails, specLoan, bridAmountInfoList)
    // 不管有没有被警告，都要放进新的结果数组中
    warnedSPlanDetailArr.push(xqPlanInfo)
  }
  return warnedSPlanDetailArr
}

/**
 * 2.构造小期中-有警告的报告数据
 *
 * @param {Object} specPlanBasicInfo 专项计划基本信息
 * @param {Array} specPlanFilingDetails 待处理的计划项列表
* @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @return {Array} 有警告的小期报告数据
 */
export function buildWarnedReportData (specPlanBasicInfo, specPlanFilingDetails, specLoan, bridAmountInfoList) {
  let warnedArr = []
  if (Vue.prototype.UtilJs.isEmpty(specPlanFilingDetails) || Vue.prototype.UtilJs.isEmpty(specPlanBasicInfo)) {
    return null
  }
  // 遍历每个计划项数据
  for (var curPlanItem of specPlanFilingDetails) {
    var warnPlanItem = {}
    warnPlanItem.accountId = curPlanItem.accountId
    warnPlanItem.accountName = curPlanItem.accountName
    warnPlanItem.accountCode = curPlanItem.accountCode
    warnPlanItem.accountType = curPlanItem.accountType
    warnPlanItem.accountValue = curPlanItem.accountValue
    warnPlanItem.accountValueType = curPlanItem.accountValueType
    warnPlanItem.specialPlanFilingId = curPlanItem.specialPlanFilingId
    warnPlanItem.correAccountFlag = curPlanItem.correAccountFlag
    warnPlanItem.children = curPlanItem.children
    warnPlanItem.delStatus = curPlanItem.delStatus

    // 筛选未被删除的specPlanFilingDetails
    let effectiveDetails = specPlanFilingDetails.filter(detail => {
      return !isDeletedPlanItem(detail.delStatus)
    })
    // 3. 构造警告信息数据 [不对已删除的计划项进行检测]
    warnPlanItem.warnedInfo = !isDeletedPlanItem(warnPlanItem.delStatus) ? buildPlanItemWarnedInfo(curPlanItem, specPlanBasicInfo, effectiveDetails, specLoan, bridAmountInfoList) : {}
    // 不管有没有被警告，都要放进新的结果数组中
    warnedArr.push(warnPlanItem)
  }

  return warnedArr
}

/**
 * 3. 构造警告信息数据-->不能把已删除的计划项当做判断条件！
 * TODO 每一个检测项都应由开关控制，确定当前是否需要检测
 *    一天当中可能有多个计划项，对每个计划项都进行检测：
 *    > 检测一：计划选项顺序
 *    > 检测二：计划项持续天数检测
 *    > 检测三：过桥约束检测
 * @param {Array} planItem 计划项
 * @param {Object} specPlanBasicInfo 专项计划基本信息
 * @param {Array} specPlanFilingDetails 专项计划详细信息（计划项列表）
 * @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @returns {Array} 有警告的计划项数据
 */
export function buildPlanItemWarnedInfo (planItem, specPlanBasicInfo, specPlanFilingDetails, specLoan, bridAmountInfoList) {
  if (Vue.prototype.UtilJs.isEmpty(planItem) || Vue.prototype.UtilJs.isEmpty(specPlanFilingDetails) || Vue.prototype.UtilJs.isEmpty(bridAmountInfoList)) {
    return null
  }
  let warnedInfo = {
    isWarned: false,
    warnedMsg: ''
  }
  // 构造计划项开始、结束日期
  let planST = getPlanItemSD(planItem)
  let planET = getPlanItemED(planItem)

  // ***** 检测零：计划项时间检测 ***** //
  let dateCheckedResult = checkDate(planST, planET)

  // ***** 检测一：计划选项顺序 ***** //
  let orderCheckedResult = checkPlanOrder(planST, planItem, specPlanFilingDetails)

  // ***** 检测二：计划项持续天数 ***** //
  let keepDaysCheckedResult = checkKeepDays(planST, planET, planItem)

  // ***** 检测三：过桥约束 ***** //
  let bridgeCheckedResult = isBridgePlanItem(planItem.accountCode) ? (checkBridge(planST, planItem, specPlanBasicInfo, specPlanFilingDetails, specLoan, bridAmountInfoList)) : {isTrue: true, errMsg: ''}

  // 构造计划项警告信息
  warnedInfo.isWarned = !(dateCheckedResult.isTrue && orderCheckedResult.isTrue && keepDaysCheckedResult.isTrue && bridgeCheckedResult.isTrue)
  warnedInfo.warnedMsg = '' + dateCheckedResult.errMsg + orderCheckedResult.errMsg + keepDaysCheckedResult.errMsg + bridgeCheckedResult.errMsg
  return warnedInfo
}

/**
 * 计划项日期检测：开始日和结束日都不属于周末和节假日
 * @param {String} planST 计划项开始日
 * @param {String} planET 计划项结束日
 * @returns {*} 检测结果：当前计划项的日期是否正确 & 警告提示
 */
export function checkDate (planST, planET) {
  var dateCheckRes = {
    isTrue: true,
    errMsg: ''
  }
  dateCheckRes.isTrue = !isDefHoliday(planST) && !isDefHoliday(planET)
  dateCheckRes.errMsg += isDefHoliday(planST) ? '计划项开始日不能是节假日! ' : ''
  dateCheckRes.errMsg += isDefHoliday(planET) ? '计划项结束日不能是节假日! ' : ''
  return dateCheckRes
}

/**
 * 检测计划先后顺序
 * TODO 待优化【代码优化(判断条件抽成)、国际化】
 * 时间先后顺序应满足
 * 【20190529确认：1.提单和律所的关系是用结束时间算，提单和律所可以拉到和后面的计划项并行
 *    2.一个专项计划中有多个提单，若（提单1开始时间===提单2开始时间 && 提单1结束时间===提单2结束时间）时，报错
 * 】
 *   {提单开始日1 < 律所进场开始日2 < 过桥日3          <= 缴款日5 <= 发行日6
 *                                  定稿日3 < 配售日4  < 缴款日5 <= 发行日6}
 *      1.1 提单1 < 律所进场1 && 提单2 < 律所进场2
 *      1.2 过桥 <= 缴款<= 发行
 *      1.3 定稿 < 配售 < 缴款 <= 发行
 *      1.4 律所进场必须在对应的提单日2-4日之内开始：提单结束日+2<=律所进场开始日<=提单结束日+4
 *      1.5 过桥和定稿先后顺序不一定，过桥和配售先后顺序也不一定，谁先谁后都可以，但是定稿<配售
 * @param {String} curItemSD 待检测计划项开始时间
 * @param {Object} curItem 待检测计划项
 * @param {Array} planItemArr 当前专项计划的计划数组
 * @returns {*} 检测结果：当前计划项的顺序是否正确 & 警告提示
 */
export function checkPlanOrder (curItemSD, curItem, planItemArr) {
  let isTrue = true
  let orderErrMsg = ''
  const curItemOrder = getPlanItemDefineOrderByCode(curItem.accountCode)

  // 遍历 planIemArr
  planItemArr.forEach(item => {
    let itemSD = getPlanItemSD(item)
    let itemED = getPlanItemED(item)
    // 和非自己的计划项进行比较
    if (compareDate(itemSD, curItemSD) !== 0 || curItem.accountId !== item.accountId || (curItem.accountId === item.accountId && curItem.correAccountFlag !== item.correAccountFlag)) {
      let itemOrder = getPlanItemDefineOrderByCode(item.accountCode)
      if (curItemOrder <= 0 || itemOrder <= 0) {
        isTrue = false
        orderErrMsg = '计划项定义错误，没有顺序小于0的计划项!' + JSON.stringify(curItem)
        return false // 跳出forEach循环
      } else if (curItemOrder > 0 && itemOrder > 0 && curItemOrder < itemOrder) {
        let type = ORDER_TYPE_LESS_THAN // 顺序小于
        if (!specialOrderCheck(curItemOrder, itemOrder, curItem, item, curItemSD, itemSD, type) && compareDate(curItemSD, itemSD) >= 0) { // curItemSD >= itemSD
          isTrue = false
          orderErrMsg = '计划项顺序错误，' + getTrueOrderMsg(curItem.accountCode)
          return false
        }
      } else if (curItemOrder > 0 && itemOrder > 0 && curItemOrder === itemOrder) {
      //   console.log('计划项顺序相同，不进行日期先后顺序限制....')
        if (curItem.accountId === item.accountId && curItem.accountCode === 'KM2001' && compareDate(itemSD, curItemSD) === 0 &&
          compareDate(itemED, getPlanItemED(curItem)) === 0) { // 提单和提单作比较：若（提单1开始时间===提单2开始时间 && 提单1结束时间===提单2结束时间）时，报错
          isTrue = false
          orderErrMsg = '计划项顺序错误，提单和提单之间的开始、结束日不能全相等！'
          return false
        }
      } else if (curItemOrder > 0 && itemOrder > 0 && curItemOrder > itemOrder) {
        let type = ORDER_TYPE_MORE_THAN // 顺序大于
        if (curItemOrder === 2 && itemOrder === 1 && curItem.correAccountFlag === item.correAccountFlag &&
          !(compareDate(curItemSD, getFormatDateBeforeOrAfter(itemED, 2)) >= 0 && compareDate(curItemSD, getFormatDateBeforeOrAfter(itemED, 4)) <= 0)) { // 若不满足[提单结束日+2 <= 律所进场开始日 <= 提单结束日+4]，则返回false
          isTrue = false
          orderErrMsg = '计划项顺序错误，' + getTrueOrderMsg(curItem.accountCode)
          console.log('律所进场应在提单结束之后的2~4天内开始[提单结束日+2<=律所进场开始日<=提单结束日+4]')
          return false
        } else if (!specialOrderCheck(curItemOrder, itemOrder, curItem, item, curItemSD, itemSD, type) && compareDate(curItemSD, itemSD) <= 0) { // curItemSD <= itemSD
          isTrue = false
          orderErrMsg = '计划项顺序错误，' + getTrueOrderMsg(curItem.accountCode)
          return false
        }
      }
    }
  })
  return {isTrue: isTrue, errMsg: orderErrMsg}
}

/**
 * 特殊顺序检测
 * @param {Number} curItemOrder 待检测项顺序
 * @param {Number} itemOrder 对比项顺序
 * @param {String} curItem 待检测计划项
 * @param {String} item 对比计划项
 * @param {String} curItemSD 待检测计划项开始时间
 * @param {String} itemSD 对比计划项开始时间
 * @param {String} type 类型（'L':curItemOrder<itemOrder ; 'M':curItemOrder>itemOrder）
 * @returns {boolean} 特殊顺序检测处理结果
 */
function specialOrderCheck (curItemOrder, itemOrder, curItem, item, curItemSD, itemSD, type) {
  switch (type) {
    case ORDER_TYPE_LESS_THAN : return specialOrderLessCheck(curItemOrder, itemOrder, curItem, item, curItemSD, itemSD)
    case ORDER_TYPE_MORE_THAN : return specialOrderMoreCheck(curItemOrder, itemOrder, curItem, item, curItemSD, itemSD)
    default : return true
  }
}

/**
 * 特殊顺序[顺序小于]检测处理
 * @param {Number} curItemOrder 待检测项顺序
 * @param {Number} itemOrder 对比项顺序
 * @param {String} curItem 待检测计划项
 * @param {String} item 对比计划项
 * @param {String} curItemSD 待检测计划项开始时间
 * @param {String} itemSD 对比计划项开始时间
 * @returns {boolean} 特殊顺序检测处理结果
 */
function specialOrderLessCheck (curItemOrder, itemOrder, curItem, item, curItemSD, itemSD) {
  if (((curItemOrder === 3 && itemOrder === 5 && curItem.accountName === '过桥' && item.accountName === '缴款') || (curItemOrder === 5 && itemOrder === 6)) &&
  compareDate(curItemSD, itemSD) <= 0) {
    // console.log('过桥<=缴款<=发行...')
    return true
  } else if (curItemOrder === 3 && itemOrder === 4 && curItem.accountName === '过桥' && item.accountName === '配售') {
    // console.log('过桥不和配售做顺序比较')
    return true
  } else if (curItemOrder === 1 && itemOrder === 2 && curItem.correAccountFlag !== item.correAccountFlag) {
    // console.log('提单不和非对应的律所进场项做顺序比较')
    return true
  }
  return false
}

/**
 * 特殊顺序[顺序大于]检测处理
 * @param {Number} curItemOrder 待检测项顺序
 * @param {Number} itemOrder 对比项顺序
 * @param {String} curItem 待检测计划项
 * @param {String} item 对比计划项
 * @param {String} curItemSD 待检测计划项开始时间
 * @param {String} itemSD 对比计划项开始时间
 * @returns {boolean} 特殊顺序检测处理结果
 */
function specialOrderMoreCheck (curItemOrder, itemOrder, curItem, item, curItemSD, itemSD) {
  if (curItemOrder === 2 && itemOrder === 1 && curItem.correAccountFlag !== item.correAccountFlag) {
    // console.log('律所进场不和非对应的提单项做顺序比较')
    return true
  } else if (curItemOrder === 4 && itemOrder === 3 && curItem.accountName === '配售' && item.accountName === '过桥') {
    // console.log('配售不和过桥做顺序比较....')
    return true
  } else if (curItemOrder === 5 && itemOrder === 3 && compareDate(curItemSD, itemSD) >= 0) { // 缴款日可以和过桥日相等
    // console.log('缴款>=过桥...')
    return true
  } else if (curItemOrder === 6 && itemOrder === 5 && compareDate(curItemSD, itemSD) >= 0) { // 发行日可以和缴款日相等
    // console.log('发行>=缴款...')
    return true
  }
  return false
}

/**
 * 检测计划项持续天数 [律所进场持续时间4-8日 （此规则作为开关，默认关闭）]
 *
 * @param {String} planST 计划项开始时间
 * @param {String} planET 计划项结束时间
 * @param {Object} planItem 待检测计划项
 * @returns {*} 检测结果：当前计划项的持续天数是否正确 & 警告提示
 */
export function checkKeepDays (planST, planET, planItem) {
  if (!isNeedCheckKeeyDays(planItem.accountCode)) {
    // 当前计划项不需要进行持续天数的检测
    return {isTrue: true, errMsg: ''}
  }
  let itemKeepDays = computeDateDiff(planST, planET) + 1
  let isTrue = itemKeepDays >= getConstraintKeepDays(planItem.accountCode).minKeepDays && itemKeepDays <= getConstraintKeepDays(planItem.accountCode).maxKeepDays
  let keepDaysErrMsg = ''
  if (!isTrue) {
    keepDaysErrMsg = '' + planItem.accountName + '应当持续' + getConstraintKeepDays(planItem.accountCode).minKeepDays + '至' + getConstraintKeepDays(planItem.accountCode).maxKeepDays + '天！'
  }
  return {isTrue: isTrue, errMsg: keepDaysErrMsg}
}

/**
 * 检测过桥约束
 *      3.1 检测过桥额度：是否超过当前可用额度
 *      3.2 是否达到单期最小使用天数（发行日-过桥日）
 *      3.3 是否跨月
 *      3.4 是否跨季
 *      3.5 是否跨年
 *      3.6 是否满足托管行需求：专项计划的托管行id是否满足过桥机构的绑定托管需求
 * @param {String} planST 计划项开始时间
 * @param {Object} planItem 待检测计划项
 * @param {Object} specPlanBasicInfo 专项计划基本信息
 * @param {Array} specPlanFilingDetails 当前专项计划的计划项数组
 * @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @returns {*} 检测结果：当前计划项的持续天数是否正确 & 警告提示
 */
export function checkBridge (planST, planItem, specPlanBasicInfo, specPlanFilingDetails, specLoan, bridAmountInfoList) {
  let bridgeCheckRes = {
    isTrue: true,
    errMsg: ''
  }

  let specialPlanId = specPlanBasicInfo.specialPlanId
  let coreEnterpriseId = specPlanBasicInfo.coreEnterpriseId
  let projectId = specPlanBasicInfo.projectId
  let custodianBankId = specPlanBasicInfo.custodianBankId

  // 获取发行日
  let releaseDate = getReleaseDate(specPlanFilingDetails)

  // 获取过桥信息(一个专项计划 : n个过桥信息，一个过桥项:n个分批分档放款计划，1个分批分档放款计划：1个过桥机构额度信息)
  let lendingBathes = (!Vue.prototype.UtilJs.isEmpty(planItem.correAccountFlag) && !isNaN(parseInt(planItem.correAccountFlag))) ? (parseInt(planItem.correAccountFlag) + 1) : null
  // 获取过桥额度信息列表
  let bridgeInfoArr = getBridgeAmountInfo(specialPlanId, lendingBathes, specLoan, bridAmountInfoList)

  // 遍历过桥机构额度信息，对每个机构额度信息进行过桥约束检测
  for (var bridgeInfo of bridgeInfoArr) {
    let minUseDays = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.minimumOccupyTime) && !isNaN(parseInt(bridgeInfo.minimumOccupyTime))) ? parseInt(bridgeInfo.minimumOccupyTime) : 0
    let maxUseDays = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.maximumOccupyTime) && !isNaN(parseInt(bridgeInfo.maximumOccupyTime))) ? parseInt(bridgeInfo.maximumOccupyTime) : 999
    let isCrossMonth = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.canExtendMonth) && bridgeInfo.canExtendMonth === '1')
    let isCrossQuarter = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.canExtendQuarter) && bridgeInfo.canExtendQuarter === '1')
    let isCrossYear = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.canExtendYear) && bridgeInfo.canExtendYear === '1')
    let isBindCustody = (!Vue.prototype.UtilJs.isEmpty(bridgeInfo) && !Vue.prototype.UtilJs.isEmpty(bridgeInfo.bundledCustodyFlag) && bridgeInfo.bundledCustodyFlag === '1')
    // 获取对应过桥额度信息的ABS分批分档信息
    let specLoanInfo = specLoan.find(item => {
      return item.specialPlanId === specialPlanId && item.lendingBatches === lendingBathes && item.bridcroquotInfoId === bridgeInfo.keyId
    })
    // 构造额度检测所需参数
    const bridcrossinsId = bridgeInfo.bridcrossinsId
    const provisionalQuotaStatus = bridgeInfo.provisionalQuotaStatus
    const bridAmount = Vue.prototype.UtilJs.isEmpty(specLoanInfo) ? 0 : specLoanInfo.lendingAmount

    // 1.检测过桥额度
    let amountCheckedRes = checkBridgeAmount(coreEnterpriseId, projectId, custodianBankId, planST, releaseDate, bridAmountInfoList, bridcrossinsId, provisionalQuotaStatus, bridAmount)
    // 2.检测单期使用天数
    let useDaysCheckedRes = checkBridgeUseDays(planST, releaseDate, minUseDays, maxUseDays)
    // 3.检测时间跨度（跨月、跨季、款年）
    let timeCrossCheckedRes = checkBridgeTimeCross(planST, releaseDate, isCrossMonth, isCrossQuarter, isCrossYear)
    var custodyCheckedRes = { isTrue: true, errMsg: '' }
    // 4.检测托管行
    if (isBindCustody) {
      custodyCheckedRes = checkBridgeCustody(bridgeInfo.bridcrossinsId, specPlanBasicInfo)
    }

    // 构造检查结果
    bridgeCheckRes.isTrue = bridgeCheckRes.isTrue && amountCheckedRes.isTrue && useDaysCheckedRes.isTrue && timeCrossCheckedRes.isTrue && custodyCheckedRes.isTrue
    bridgeCheckRes.errMsg = bridgeCheckRes.errMsg + amountCheckedRes.errMsg + useDaysCheckedRes.errMsg + timeCrossCheckedRes.errMsg + custodyCheckedRes.errMsg
  }
  return bridgeCheckRes
}

/**
 * 检测过桥额度
 * @param {String} coreEnterpriseId 核心企业ID
 * @param {String} projectId 项目ID
 * @param {String} custodianBankId 托管行ID
 * @param {*} bridDate 过桥日
 * @param {*} releaseDate 发行日
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @param {String} bridcrossinsId 过桥机构Id
 * @param {String} provisionalQuotaStatus 是否临时额度
 * @param {Number} bridAmount 过桥金额
 * @returns {Object} 过桥额度检测结果
 */
export function checkBridgeAmount (coreEnterpriseId, projectId, custodianBankId, bridDate, releaseDate, bridAmountInfoList, bridcrossinsId, provisionalQuotaStatus, bridAmount) {
  var bridgeAmontCheckRes = {
    isTrue: true,
    errMsg: ''
  }
  // 获取过桥可用额度
  let canUseAmountInfo = getBridgeCanUseAmout(coreEnterpriseId, projectId, custodianBankId, bridDate, releaseDate, bridAmountInfoList)
  const bridInsCode = '' + bridcrossinsId + '_' + provisionalQuotaStatus
  let res = canUseAmountInfo.find(item => { return item.bridcrossinsCode === bridInsCode })
  let canUseAmount = (!Vue.prototype.UtilJs.isEmpty(res) && !Vue.prototype.UtilJs.isEmpty(res.canUseAmount) && !isNaN(parseInt(res.canUseAmount))) ? parseInt(res.canUseAmount) : 0
  bridgeAmontCheckRes.isTrue = canUseAmount >= parseInt(bridAmount)
  bridgeAmontCheckRes.errMsg = bridgeAmontCheckRes.isTrue ? bridgeAmontCheckRes.errMsg : '过桥额度检测失败，计划过桥金额[' + bridAmount + ']不能超过可用额度[' + canUseAmount + ']!'
  return bridgeAmontCheckRes
}

/**
 * 检测过桥单期使用天数，应满足[minUseDays <= (发行日-过桥日）<= maxUseDays]
 * 若(发行日-过桥日）< minUseDays || (发行日-过桥日）> maxUseDays,检测结果为false
 * @param {*} bridgeDate 过桥日
 * @param {*} releaseDate 发行日
 * @param {Number} minUseDays 最小使用天数
 * @param {Number} maxUseDays 最大使用天数
 * @returns {Object} 过桥单期使用天数验证结果
 */
export function checkBridgeUseDays (bridgeDate, releaseDate, minUseDays, maxUseDays) {
  let isTrue = true
  let errMsg = ''
  // 使用天数 = 间隔日天数 + 过桥那天
  let useDays = computeDateDiff(releaseDate, bridgeDate) + 1
  if (minUseDays > 0 && maxUseDays > 0 && maxUseDays >= minUseDays) {
    isTrue = (useDays >= minUseDays && useDays <= maxUseDays)
    errMsg = isTrue ? errMsg : '过桥单期使用天数不合理，应使用' + minUseDays + '天' + '至' + maxUseDays + '天!'
  }
  return {isTrue: isTrue, errMsg: errMsg}
}

/**
 * 检测过桥时间跨度约束
 * @param {*} bridgeDate 过桥日
 * @param {*} releaseDate 发行日
 * @param {boolean} isCrossMonth 是否可跨月
 * @param {boolean} isCrossQuarter 是否可跨季度
 * @param {boolean} isCrossYear 是否可跨年
 * @returns {Object} 验证结果
 */
export function checkBridgeTimeCross (bridgeDate, releaseDate, isCrossMonth, isCrossQuarter, isCrossYear) {
  let isTrue = true
  let errMsg = ''
  // 检测是否跨月
  if (!isCrossMonth && !isCommonMonth(bridgeDate, releaseDate)) {
    isTrue = false
    errMsg += '不可跨月！'
  }
  // 检测是否跨季
  if (!isCrossQuarter && !isCommonQuarter(bridgeDate, releaseDate)) {
    isTrue = false
    errMsg += '不可跨季度!'
  }
  // 检测是否跨年
  if (!isCrossYear && !isCommonYear(bridgeDate, releaseDate)) {
    isTrue = false
    errMsg += '不可跨年!'
  }
  return { isTrue: isTrue, errMsg: errMsg }
}

/**
 * 检测过桥托管行
 * @param {String} bridgeInstitutionId 过桥机构Id
 * @param {Object} specialPlanBasic 专项计划基本信息
 * @returns {Object} 过桥托管行检测结果
 */
export function checkBridgeCustody (bridgeInstitutionId, specialPlanBasic) {
  if (specialPlanBasic && !Vue.prototype.UtilJs.isEmpty(specialPlanBasic) && !Vue.prototype.UtilJs.isEmpty(specialPlanBasic.custodianBankId) &&
    bridgeInstitutionId === specialPlanBasic.custodianBankId) {
    return { isTrue: true, errMsg: '' }
  }
  return { isTrue: false, errMsg: '过桥机构应为托管行' + specialPlanBasic.custodianBankName + '!' }
}

/**
 * 获取发行日
 * @param {Array} specPlanFilingDetails 当前专项计划的计划项数组
 * @returns {*} 专项计划发行日
 */
export function getReleaseDate (specPlanFilingDetails) {
  if (Vue.prototype.UtilJs.isEmpty(specPlanFilingDetails) || specPlanFilingDetails.length <= 0) {
    return null
  }
  const releaseCode = getReleasePlanAccountCode()
  let releasePlanItem = specPlanFilingDetails.find(plan => {
    return releaseCode === plan.accountCode
  })
  return Vue.prototype.UtilJs.isEmpty(releasePlanItem) ? null : getPlanItemSD(releasePlanItem)
}

/**
 * 获取对应的过桥机构额度基本信息
 * @param {String} specialPlanId 专项计划ID
 * @param {String} lendingBathes 放款批次
 * @param {Array} specLoan 月度计划分档分批放款信息
 * @param {Array} bridAmountInfoList 过桥机构额度信息列表
 * @returns {Array} 过桥机构额度信息数组
 */
function getBridgeAmountInfo (specialPlanId, lendingBathes, specLoan, bridAmountInfoList) {
  // 根据specialPlanId筛选specLoan
  var bridgeLendInfo = specLoan.filter(specLoanItem => {
    return specLoanItem.specialPlanId === specialPlanId
  })
  var ids = []
  if (!Vue.prototype.UtilJs.isEmpty(bridgeLendInfo) && bridgeLendInfo.length > 0) {
    bridgeLendInfo.forEach(item => {
      if (Vue.prototype.UtilJs.isEmpty(lendingBathes)) { // 若不传放款批次，默认加载的是当前专项计划的所有过桥额度信息
        ids.push(item.bridcroquotInfoId)
      } else if (!Vue.prototype.UtilJs.isEmpty(item.lendingBatches) && item.lendingBatches === lendingBathes) {
        ids.push(item.bridcroquotInfoId)
      }
    })
  }
  // ids去重[业务上不会存在外键id值相同的记录，对于同一批次的分批分档放款信息来说bridcroquotInfoId唯一确定一条记录]
  // ids = Array.from(new Set(ids))
  // 根据ids筛选bridAmountInfoList
  var bridgeInfo = bridAmountInfoList.filter(bridAmountInfo => {
    var index = ids.findIndex(id => { return id === bridAmountInfo.keyId })
    return index !== -1
  })
  return bridgeInfo
}

/**
 * 判断是否已删除的计划项
 * @param {Number} delStatus 删除状态
 * @returns {Boolean} 判断结果：true是，false否
 */
export function isDeletedPlanItem (delStatus) {
  return !(!Vue.prototype.UtilJs.isEmpty(delStatus) && delStatus === DEL_STATUS_0)
}
